import 'package:flutter/material.dart';

class TTStarRating extends StatefulWidget {
  TTStarRating({
    @required this.rating,
    this.maxRating = 10,
    this.size = 30,
    this.selectedColor = const Color(0xffbbbbbb),
    this.unselectedColor = const Color(0xffe0aa46),
    Widget selectedImage,
    Widget unselectedImage,
    this.count = 5,
  })  : selectedImage = selectedImage ??
            Icon(
              Icons.star,
              size: size,
              color: selectedColor,
            ),
        unselectedImage = unselectedImage ??
            Icon(
              Icons.star,
              size: size,
              color: unselectedColor,
            );

  final double rating;
  final double maxRating;
  final Widget selectedImage;
  final Widget unselectedImage;
  final int count;
  final double size;
  final Color selectedColor;
  final Color unselectedColor;

  @override
  _TTStarRatingState createState() => _TTStarRatingState();
}

class _TTStarRatingState extends State<TTStarRating> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Stack(
        children: [
          Row(children: _getUnselectedImage(), mainAxisSize: MainAxisSize.min),
          Row(children: _getSelectedImage(), mainAxisSize: MainAxisSize.min),
        ],
      ),
    );
  }

  /// 获取未选中的星星
  List<Widget> _getUnselectedImage() {
    return List.generate(widget.count, (index) => widget.unselectedImage);
  }

  /// 获取选中的星星
  List<Widget> _getSelectedImage() {
    // 1. 计算 Star 个数和剩余比例等
    double oneValue = widget.maxRating / widget.count;
    int entireCount = (widget.rating / oneValue).floor();
    double leftValue = widget.rating - entireCount * oneValue;
    double leftRatio = leftValue / oneValue;

    // 2. 获取 Star
    List<Widget> selectedImages = [];
    for (int i = 0; i < entireCount; i++) {
      selectedImages.add(widget.selectedImage);
    }

    // 3. 计算
    Widget leftStar = ClipRect(
      clipper: TTStarRectClipper(width: leftRatio * widget.size),
      child: widget.selectedImage,
    );

    selectedImages.add(leftStar);

    return selectedImages;
  }
}

class TTStarRectClipper extends CustomClipper<Rect> {
  final double width;

  TTStarRectClipper({this.width});

  @override
  Rect getClip(Size size) {
    return Rect.fromLTRB(0, 0, width, size.height);
  }

  @override
  bool shouldReclip(TTStarRectClipper oldClipper) {
    return width != oldClipper.width;
  }
}
